/*
 * Tablero.h
 *      Author: sebastian
 */

#ifndef TABLERO_H_
#define TABLERO_H_
#include "Celda.h"
#include <string>
#include <iostream>
#include "GeneradorCelda.h"
#include <vector>
#include <string.h>
#include "../Common/Jsonizable.h"
#include "../Common/CargaJson.h"
#include <sstream>

#define ORIENTACION_VERTICAL 0
#define ORIENTACION_HORIZONTAL 1
#define PUNTAJEUNIDADMATCH3 10
#define PUNTAJEUNIDADMATCH4 20
#define PUNTAJEUNIDADMAMATCHMASDE5 30
#define PUNTAJEUNIDADESPECIAL 40

class Tablero : Jsonizable {
private:
	GeneradorCelda generador;
	std::vector<GeneradorCelda*> generadorColumna;

	Celda* tablero;
	unsigned int cantFilas;
	unsigned int cantColumnas;


	//Devuelve una referencia a un celda del tablero.
	Celda& getCelda(int columna, int fila);

	//Intercambia dos celdas del tablero.
	void intercambiarDosCeldas(int filaInicial,int colInicial,
			int filaFinal, int colFinal);

	//devuelve un vector con las celdas de un match horizontal.
	std::vector<Celda*> hayMatchHorizontal(int fila, int columna);

	//devuelve un vector con las celdas de un match vertical.
	std::vector<Celda*> hayMatchVertical(int fila, int columna);

	//Comprueba si hubo algun match.
	//0 no hubo match.
	// 0> puntaje obtenido.
	int comprobarMatch(int fila, int columna,int orientacion);

	//Marca una fila para que luego sea eliminada.
	int marcarEliminarFila(int fila);

	//Marca una columna para que luego sea eliminada.
	int marcarEliminarColumna(int columna);

	//Marca para que todo el tablero sea eliminado.
	int marcarEliminarTablero();

	//Marca a eliminar dado un tipo de celda.
	int marcarEliminarDadoUnTipo(unsigned int tipo);

	//Marca a eliminar las celdas que estan dentro del vector.
	void marcarABorrar(std::vector<Celda*>& vector);

	//Comprueba que lo que se quiera mover este dentro de las dimensiones
	//posibles ; -1 error por la fila, 0 OK, 1 error por la columna
	int comprobarConDimensiones(int filaInicial, int colInicial, int filaFinal, int colFinal);

	//comprueba que el movimiento sea entre celdas adyacentes
	// 0 OK, -1 error
	int comprobarAdyacencia(int filaInicial, int colInicial, int filaFinal, int colFinal);

	//Comprueba si dentro del match hubo una miniBar.
	//Si la hubo, elimina la fila.
	int comprobarMiniBarHorizontal(std::vector<Celda*>& vector);

	//Comprueba si dentro del match hubo una miniBar.
	//Si la hubo, elimina la columna.
	int comprobarMiniBarvertical(std::vector<Celda*>& vector);

	//Carga los generadores de las columnas
	void cargaGeneradoresColumnas(Json::Value& root);

	//Carga las celdas inciales con las probabilidades especificadas en root
	void cargaCeldasIniciales(Json::Value& root);

	//Verifica los casos especiales, estrella button, minibar estrella, etc
	int especiales(int filaInicial, int colInicial, int filaFinal, int colFinal);

public:
	Tablero(Json::Value& root);

	Tablero(const Tablero& tablero);

	//Dibuja el tablero.
	void dibujarTablero() const;

	//Mueve 2 celdas
	// 0 = no hubo match.
	// 0> el puntaje obtenido.
	int mover(int filaInicial, int colInicial,int filaFinal, int colFinal);

	//Busca si hay algun match en el tablero.
	int buscarMatchLuegoDeMover();

	//Dado un match, sube las celdas matcheadas, baja las que no.
	void bajarCeldas();

	//True si hay mas movimientos en el tablero, False, si no.
	bool hayMasMovimientos();

	//Recarga las celdas vacias con nuevos valores.
	void recargarVacios();

	//Devuelve el tablero.
	Celda* getTab();

	//Devuelve la cantidad de filas del tablero.
	int getCantidadFilas();

	//Devuelve la cantidad de Columnas del tablero.
	int getCantidadColumnas();

	//Devuelve el tablero Jsonizado.
	Json::Value getJson();

	//Setea el tablero dado un Json.
	void setJson(Json::Value&);

	//Libera memoria alocada.
	~Tablero();
};

#endif /* TABLERO_H_ */
